<template>
    <Dialog :title="dialogTitle" v-model="dialogVisible">
        <el-form
                ref="formRef"
                :model="formData"
                :rules="formRules"
                label-width="100px"
                v-loading="formLoading || keyLoading || deptLoading"
        >
            <!-- 原有表单字段保持不变 -->
            <el-form-item label="用户名" prop="name">
                <el-input v-model="formData.name" placeholder="请输入用户名" />
            </el-form-item>
            <el-form-item label="用户昵称" prop="nickName">
                <el-input v-model="formData.nickName" placeholder="请输入用户昵称" />
            </el-form-item>
            <el-form-item label="手机号码" prop="telePhone">
                <el-input v-model="formData.telePhone" placeholder="请输入手机号码" />
            </el-form-item>
            <el-form-item label="微信号" prop="wechat">
                <el-input v-model="formData.wechat" placeholder="请输入微信号" />
            </el-form-item>
            <el-form-item label="电子邮箱" prop="email">
                <el-input v-model="formData.email" placeholder="请输入电子邮箱" />
            </el-form-item>

            <!-- 新增：部门选择下拉框（树形结构，支持搜索） -->
            <el-form-item label="所属部门" prop="orgCode">
                <el-tree-select
                        v-model="formData.orgCode"
                        :data="deptTreeList"
                        :props="deptTreeProps"
                        placeholder="请选择所属部门"
                        clearable
                        filterable
                        style="width: 100%"
                        @change="handleDeptChange"
                />
            </el-form-item>

            <!-- 新增时显示密码框，编辑时隐藏 -->
            <el-form-item
                    v-if="formType === 'create'"
                    label="密码"
                    prop="password"
            >
                <el-input
                        v-model="formData.password"
                        type="password"
                        placeholder="请输入密码（6-20位字母/数字组合）"
                        show-password
                />
            </el-form-item>
        </el-form>
        <template #footer>
            <el-button @click="submitForm" type="primary" :disabled="formLoading || keyLoading || deptLoading">确 定</el-button>
            <el-button @click="dialogVisible = false">取 消</el-button>
        </template>
    </Dialog>
</template>
<script setup lang="ts">
import { UserApi, User } from '@/api/portal/user'
import JSEncrypt from 'jsencrypt' // 引入RSA加密库
import { SecurityApi } from '@/api/system/security' // 引入获取公钥的API
// 1. 新增：引入部门相关API和工具函数
import { DeptApi, Dept } from '@/api/portal/dept'
import { handleTree } from '@/utils/tree'
import { useMessage } from '@/hooks/web/useMessage'

/** 门户网站用户 表单（新增/编辑） */
defineOptions({ name: 'UserForm' })

const message = useMessage() // 消息弹窗

// 弹窗控制
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const keyLoading = ref(false) // 获取公钥加载状态
// 2. 新增：部门加载状态（控制表单loading）
const deptLoading = ref(false)
const formType = ref<'create' | 'update'>('create') // 表单类型：新增/编辑

// 加密相关
const publicKey = ref('') // RSA公钥
const encryptor = new JSEncrypt() // 加密实例

// 3. 新增：部门树形数据和配置
const deptTreeList = ref<any[]>([]) // 部门树形结构数据
const deptTreeProps = ref({ // 树形选择器配置（匹配部门数据字段）
    value: 'orgCode', // 部门编码（作为选中值的字段）
    label: 'name', // 部门名称（显示文本的字段）
    children: 'children' // 子部门字段
})

// 4. 改造：表单数据新增部门编码字段（与后端用户表的部门关联字段对应）
const formData = ref({
    id: undefined,
    name: undefined,
    nickName: undefined,
    telePhone: undefined,
    wechat: undefined,
    email: undefined,
    password: undefined,
    orgCode: undefined, // 新增：用户所属部门编码（核心关联字段）
    deptName: undefined // 可选：存储部门名称（用于回显或其他场景，非必须）
})

// 5. 改造：表单校验规则新增部门必填校验
const formRules = reactive({
    name: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
    telePhone: [
        { required: true, message: '手机号码不能为空', trigger: 'blur' },
        { pattern: /^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/, message: '请输入正确的手机号码格式', trigger: 'blur' }
    ],
    password: [{
        required: true,
        message: '密码不能为空',
        trigger: 'blur'
    }],
    // 新增：部门选择必填校验
    orgCode: [{ required: true, message: '请选择所属部门', trigger: 'blur' }]
})

const formRef = ref()

/** 获取RSA公钥（原有逻辑不变） */
const fetchPublicKey = async () => {
    if (publicKey.value) return true // 公钥已存在则直接返回
    try {
        keyLoading.value = true
        const res = await SecurityApi.getPublicKey()
        publicKey.value = res.publicKey
        encryptor.setPublicKey(publicKey.value) // 设置公钥
        return true
    } catch (error) {
        message.error('获取加密公钥失败，请重试')
        return false
    } finally {
        keyLoading.value = false
    }
}

/** RSA加密密码（原有逻辑不变） */
const encryptPassword = (data: string) => {
    if (!publicKey.value) throw new Error('公钥不存在，无法加密')
    return encryptor.encrypt(data) || '' // 加密失败返回空字符串
}

// 6. 新增：获取部门树形数据（用于下拉选择）
const getDeptTree = async () => {
    deptLoading.value = true
    try {
        // 调用部门列表接口（无需筛选，获取全量部门）
        const deptList = await DeptApi.getDeptPage({})
        // 转换为树形结构（复用部门页的handleTree工具函数）
        const treeData = handleTree(deptList, 'orgCode', 'parentCode', 'children', '-')
        deptTreeList.value = treeData
    } catch (error) {
        message.error('获取部门列表失败，请重试')
        deptTreeList.value = []
    } finally {
        deptLoading.value = false
    }
}

// 7. 新增：部门选择变更时的回调（可选，如需同步部门名称等信息）
const handleDeptChange = (orgCode: string) => {
    // 从部门树形数据中匹配选中的部门名称（可选，用于formData存储部门名称）
    const findDeptName = (tree: any[], code: string) => {
        for (const node of tree) {
            if (node.orgCode === code) return node.name
            if (node.children && node.children.length) {
                const childName = findDeptName(node.children, code)
                if (childName) return childName
            }
        }
        return ''
    }
    formData.value.deptName = findDeptName(deptTreeList.value, orgCode)
}

/** 打开弹窗（外部调用，改造：新增部门数据加载） */
const open = async (type: 'create' | 'update', id?: number) => {
    dialogVisible.value = true
    dialogTitle.value = type === 'create' ? '新增' : '编辑' // 直接使用中文标题
    formType.value = type
    resetForm()

    // 8. 改造：打开弹窗时先加载部门数据（无论新增/编辑都需要）
    await getDeptTree()

    // 打开弹窗时预获取公钥（尤其是新增时需要，原有逻辑不变）
    if (type === 'create') {
        fetchPublicKey().catch(() => {})
    }

    // 编辑场景：加载用户数据，清空密码字段（改造：回显用户所属部门）
    if (type === 'update' && id) {
        formLoading.value = true
        try {
            const userData = await UserApi.getUser(id)
            // 过滤password，避免后端返回的加密密码残留
            const { password, ...restData } = userData
            // 回显用户所属部门（核心：确保userData包含orgCode字段）
            formData.value = {
                ...restData,
                password: undefined,
                orgCode: restData.orgCode || undefined, // 部门编码回显
                deptName: restData.deptName || undefined // 部门名称回显（可选）
            }
        } finally {
            formLoading.value = false
        }
    }
}
defineExpose({ open }) // 暴露open方法给父组件

/** 提交表单（原有逻辑不变，自动携带orgCode字段给后端） */
const emit = defineEmits(['success']) // 提交成功触发事件
const submitForm = async () => {
    // 表单校验（自动包含部门必填校验）
    await formRef.value.validate()

    // 新增时需要加密密码，先确保获取到公钥（原有逻辑不变）
    if (formType.value === 'create') {
        const hasPublicKey = await fetchPublicKey()
        if (!hasPublicKey) return
    }

    formLoading.value = true

    try {
        const submitData = { ...formData.value } as User

        // 新增用户时加密密码（原有逻辑不变）
        if (formType.value === 'create' && submitData.password) {
            const encryptedPassword = encryptPassword(submitData.password)
            if (!encryptedPassword) {
                throw new Error('密码加密失败，请重试')
            }
            submitData.password = encryptedPassword // 使用加密后的密码
        } else {
            // 编辑：删除password字段，避免空值覆盖（原有逻辑不变）
            delete submitData.password
        }

        // 提交时自动携带orgCode（无需额外处理，formData已包含）
        if (formType.value === 'create') {
            await UserApi.createUser(submitData)
            message.success('创建成功')
        } else {
            await UserApi.updateUser(submitData)
            message.success('更新成功')
        }
        dialogVisible.value = false
        emit('success') // 通知父组件刷新列表
    } catch (error) {
        console.error('表单提交失败:', error)
        message.error(error instanceof Error ? error.message : '操作失败')
    } finally {
        formLoading.value = false
    }
}

/** 重置表单（改造：重置部门相关字段） */
const resetForm = () => {
    formData.value = {
        id: undefined,
        name: undefined,
        nickName: undefined,
        telePhone: undefined,
        wechat: undefined,
        email: undefined,
        password: undefined,
        orgCode: undefined, // 重置部门编码
        deptName: undefined // 重置部门名称（可选）
    }
    formRef.value?.resetFields()
}
</script>
